// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#pragma once

#include <string>
#include <unordered_set>

#include <rapidjson/rapidjson.h>

namespace coin2::exchange::upbit::api_util {

class OrderManager {
 public:
  using OrderSet = std::unordered_set<std::string>;
  using JsonValue = rapidjson::GenericValue<rapidjson::UTF8<>>;

 public:
  OrderManager() = default;
  OrderManager(const OrderManager&) = delete;
  OrderManager& operator=(const OrderManager&) = delete;

  OrderSet GetOpenOrdersCopy() const { return open_orders_; }

  void ProcessOpenOrder(const JsonValue& data) {
    const std::string state = data["state"].GetString();
    if (state != "wait") {
      return;
    }
    const auto order_id = data["uuid"].GetString();
    AddOpenOrder(order_id);
  }

  void ProcessClosedOrder(const JsonValue& data) {
    const std::string state = data["state"].GetString();
    if (state == "wait") {
      return;
    }
    const auto order_id = data["uuid"].GetString();
    DelOpenOrder(order_id);
  }

  bool Find(const std::string& order_id) const { return open_orders_.count(order_id) > 0; }

  void AddOpenOrder(const std::string& order_id) {
    if (order_id.empty()) {
      return;
    }
    if (open_orders_.count(order_id) > 0) {
      return;
    }
    open_orders_.emplace(order_id);
  }

  void DelOpenOrder(const std::string& order_id) {
    if (order_id.empty()) {
      return;
    }
    if (open_orders_.count(order_id) == 0) {
      return;
    }
    open_orders_.erase(order_id);
  }

 private:
  OrderSet open_orders_;
};

}  // namespace coin2::exchange::upbit::api_util
